1 Einleitung

Wir beschäftigen uns mit den Daten des Bundesamt für Meteorologie. Wir haben dafür einen Export der Wetterstation Jungfraujoch (3571 m ü.M.) vom Jahr 2020. Diese Daten haben wir vom IDAWEB des Bundesamts für Meteorologie erhalten. Der Bestellschein ist im Anhang enthalten.

In diesem Notebook nutzen wir Plotly, um interaktive Time Series Plots zu generieren. Plotly ist eine benutzerfreundliche Datenvisualisierungssoftware, die hochentwickelte Visualisierungswerkzeuge bietet. Das Hinzufügen von Interaktion zu Visualisierungen eröffnet eine grosse Vielfalt an Möglichkeiten. wir können verschiedene Visualisierungen derselben Daten auf Abruf präsentieren, zoomen, schwenken, filtern und scrollen implementieren. Anbei findet man die Dokumentation von Plotly unter folgenden Link: https://plotly.com/r/.

Während Plotly und GGplot beide Visualisierungen generieren, haben beide Vor- und Nachteile. GGplot kann mit einer sehr simplen Syntax verwendet werden, es lassen sich aber sehr einfach und modular Komplexitäten einbauen. Die Library bietet eine grosse Bandbreite an visuellen Möglichkeiten. Allerdings verwendet GGplot2 eine unterschiedliche Syntax als restliches R. Aus unsere Sicht ist der grösste Nachteil, dass keine interaktiven Plots möglich sind.

Genau dieses Manko füllt Plotly, welches automatisch interaktive Grafiken erstellt. Sobald also dem Anwender Möglichkeiten wie die Auswahl von Daten, Zoom oder Selektion von Punkten ermöglicht werden sollen, ist Plotly die Alternative. Die kleinere Anzahl von Farbpaletten ist in diesem Fall nur ein kleiner Wehrmutstropfen.

2 Hypothese / Fragestellungen

  1. Es gibt viele ausgeprägte Korrelationen zwischen den verschiedenen Variablen.
  2. Über das ganze Jahr (2020) blieb die mittlere Tagestemperatur unter 0°C.
  3. Auf dem Jungfraujoch ist es kurz vor Sonnenaufgang am kältesten.
  4. Die Sonne scheint auf dem Jungfraujoch das ganze Jahr etwa gleich lange.

3 Vorbereitung

3.1 Libraries importieren

library(plotly)
library(corrplot)
library(lubridate)
library(tidyverse)
library(PerformanceAnalytics)

3.2 Data Wrangling

data_unclean <- read.csv(file = "Meteodaten.csv", sep = ";")
data_unclean <- data.frame(lapply(data_unclean, as.numeric))
data_unclean$time <- ymd_hm(data_unclean$time)
data <- data_unclean

data <- data %>%
  select(time,
    "boeenspitze" = fkl010z1, # in Meter/Sekunde
    "windgeschwindigkeit" = fkl010za, # in Meter/Sekunde
    "sonnenscheindauer" = sre000z0, # in Minuten
    "gesamtbewoelkung" = nto000s0, # in octas
    "luftfeuchtigkeit" = ure200s0, # in Prozent
    "lufttemperatur" = tre200s0, # in Grad Celsius
    "luftdruck" = prestas0 # in Hectopascal
  ) # Erweiterbar :)

4 Beantwortung der Fragestellungen

4.1 Es gibt viele ausgeprägte Korrelationen zwischen den verschiedenen Variablen.

corrData <- cor(data_unclean[3:31], use = "pairwise.complete.obs")
corrplot.mixed(corrData, lower = "ellipse", upper = "number", order = "alphabet", tl.pos = "lt", diag = "n", number.cex = 0.4)

Im ganzen Datensatz haben wir zu viele Variablen um eine verständliche Visualisierung über die Korrelationen aller Variablen zu erstellen. Jedoch lohnt sich diese Erstellung dieser Visualisierung um zu bestimmmen, welche Features man im reduzierten Datensatz übernehmen möchte. Das Bundesamt für Meteorologie hat die Namen dieser Variablen kodiert, deswegen müssen wir anhand der mitgelieferten Tabelle schauen, für was diese Codes stehen:

Parameter Einheit Beschreibung
uto200s0 g/m^2 Absolute Luftfeuchtigkeit 2 m über Boden; Momentanwert
ns2000s0 octas Betrag der mittleren Wolken
ns1000s0 octas Betrag der untersten Wolken
fkl010z1 m/s Böenspitze (Sekundenböe); Maximum
xchills0 °C Chill Temperatur; Momentanwert
pva200s0 hPa Dampfdruck 2 m über Boden; Momentanwert
pvd200s0 hPa Dampfdruckdefizit 2 m über Boden; Momentanwert
tre2desd °C Differenz Lufttemperatur 2 m über Boden - Taupunkt; Momentanwert
tpp200s0 °C Feuchtpotentielle Temperatur 2 m über Boden; Momentanwert
tps200s0 °C Feuchttemperatur (Psychrometertemperatur) 2 m über Boden; Momentanwert
nto000s0 octas Gesamtbewölkung
gor000za W/m^2 Globalstrahlung; Standardabweichung
gre000z0 W/m^2 Globalstrahlung; Zehnminutenmittel
oli000z0 W/m^2 Langwellige Einstrahlung; Zehnminutenmittel
prestas0 hPa Luftdruck auf Barometerhöhe (QFE); Momentanwert
pp0qnhs0 hPa Luftdruck reduziert auf Meeresniveau mit Standardatmosphäre (QNH); Momentanwert
tre200s0 °C Lufttemperatur 2 m über Boden; Momentanwert
pvamixs0 g/kg Mischungsverhältnis
uor200s0 % Original Luftfeuchtigkeit 2 m über Boden; Momentanwert
tpo200s0 °C Potentielle Temperatur 2 m über Boden; Momentanwert
ure200s0 % Relative Luftfeuchtigkeit 2 m über Boden; Momentanwert
sre000z0 min Sonnenscheindauer; Zehnminutensumme
usp200s0 g/kg Spezifische Luftfeuchtigkeit 2 m über Boden; Momentanwert
pvaices0 hPa Sättigungsdampfdruck über Eis; Momentanwert

Leider sind die meisten hohen Korrelationen keine richtige Korrelationen, sondern zwei Variablen, welche etwas ähnliches beschreiben oder physikalische Zusammenhänge. Beispiel dafür ist die Korrelation von sre000z0 (Sonnenscheindauer) und gre000z0 (Globalstrahlung).

Wir entscheiden uns grundsätzlich für diese Werte:

Spalte Kurzbeschrieb Definition
fkl010za Windgeschwindigkeit Die Windgeschwindigkeit ist die Geschwindigkeit der Luft gegenüber dem Boden.
sre000z0 Sonnenscheindauer Als Sonnenschein wird zweierlei bezeichnet: der Lichtschein der Sonne (also die Wirkung der Sonnenstrahlen auf die Erde), und eine Wetterlage mit geringer oder keiner Bewölkung.
nto000s0 Gesamtbewölkung Eine Schätzung, wie viele Achtel des Himmels mit Wolken bedeckt ist.
ure200s0 Luftfeuchtigkeit Die Luftfeuchtigkeit oder Luftfeuchte ist der Anteil des Wasserdampfs am Gasgemisch der Luft.
tre200s0 Lufttemperatur Als Lufttemperatur wird jene Temperatur der bodennahen Atmosphäre bezeichnet, die weder von Sonnenstrahlung noch von Bodenwärme oder Wärmeleitung beeinflusst ist.
prestas0 Luftdruck Der Luftdruck an einem beliebigen Ort der Erdatmosphäre ist der hydrostatische Druck der Luft, der an diesem Ort herrscht.

Aus folgenden Gründen:

Kurzbeschrieb Begründung
Windgeschwindigkeit Die Windgeschwindigkeit ist eine der meist beachteten Wetterkennzahlen. Wir verwenden sie zur Überprüfung der Korrelationen
Sonnenscheindauer Dieses Feature wird benötigt, um die vierte Hypothese bestätigen oder verwerfen zu können.
Gesamtbewölkung Dieses Feature wird benötigt, um die vierte Hypothese bestätigen oder verwerfen zu können.
Luftfeuchtigkeit Diese Werte verwenden wir, um mögliche Korrelationen festzustellen.
Lufttemperatur Dieses Feature wird benötigt, um die zweite und dritte Hypothese bestätigen oder verwerfen zu können.
Luftdruck Die Werte verwenden wir, um den physikalischen Zusammenhang zwischen Druck und Temperatur zu bestätigen.
corrData <- data %>%
  select(
    "boeenspitze",
    "windgeschwindigkeit",
    "sonnenscheindauer",
    "luftfeuchtigkeit",
    "lufttemperatur",
    "luftdruck",
  ) %>%
  cor(., use = "pairwise.complete.obs")

corrplot.mixed(corrData, lower = "ellipse", upper = "number", order = "alphabet", tl.pos = "lt", diag = "u")

Die einzigen ausgeprägten Korrelationen (+/- 0.7) sind Luftdruck ~ Lufttemperatur und Böenspitzen ~ Windgeschwindigkeit. Leider ist die erste Korrelation ein physikalischer Zusammenhang. Die zweite Korrelation ist auch nicht überraschend, da der Wert der Böenspitzen abhängig von der Geschwindkeit des Windes ist. Die stärkste negative Korrelation hat einen Wert von nur -0.39.

Die Hypothese verwerfen wir, da wir im kleinen Korrelationsplot nur zwei Werte über 0.7 haben. Diese sind erst noch nicht aussagekräftig, wie wir gerade beschrieben haben.

4.2 Über das ganze Jahr (2020) blieb die mittlere Tagestemperatur unter 0°C.

Hier nehmen wir 0°C als Referenz, da der Gefrierpunkt von Wasser (unter idealen Bedingungen) bei 0°C liegt. Das Jungfraujoch ist auch das obere Ende des grössten Gletschers der Schweiz. Entsprechend wäre es für diesen Gletscher schlecht, zu hohe Temperaturen erleiden zu müssen.

granularity <- "day"

plot <- data %>%
  group_by(time = floor_date(time, granularity)) %>%
  summarise(
    mean_lufttemperatur = mean(lufttemperatur, na.rm = T),
    mean_luftfeuchtigkeit = mean(luftfeuchtigkeit, na.rm = T),
    mean_windgeschwindigkeit = mean(windgeschwindigkeit, na.rm = T),
    mean_luftdruck = mean(luftdruck, na.rm = T),
    sonnenscheindauer_h = sum(sonnenscheindauer, na.rm = T) / 60
  )
plot$windchill <- (13.12 + 0.6215 * plot$mean_lufttemperatur) + (0.3965 * plot$mean_lufttemperatur - 11.37) * (plot$mean_windgeschwindigkeit * 3.6)^0.16

plot_ly(
  data = plot,
  type = "scatter",
  mode = "lines",
  width = 900,
  height = 700
) %>%
  layout(
    showlegend = TRUE,
    title = "Wetterverlauf im Jungfraujoch über das Jahr 2020",
    xaxis = list(
      title = "Zeitachse",
      rangeslider = list(visible = T),
      rangeselector = list(
        buttons = list(
          list(count = 1, label = "1m", step = "month", stepmode = "backward"),
          list(step = "all")
        )
      ),
      zerolinecolor = "#C5C5C5",
      zerolinewidth = 2,
      gridcolor = "#C5C5C5",
      type = "date"
    ),
    yaxis = list(
      title = "",
      zerolinecolor = "#C5C5C5",
      zerolinewidth = 2,
      gridcolor = "#C5C5C5"
    ),
    plot_bgcolor = "#ffff",
    margin = 0.2,
    shapes = list(
      list(
        type = "area",
        fillcolor = "lightblue",
        line = list(color = "lightblue"),
        opacity = 0.2,
        x0 = "2020-01-01",
        x1 = "2020-03-21",
        yref = "paper",
        y0 = 0,
        y1 = 1
      ),
      list(
        type = "area",
        fillcolor = "green",
        line = list(color = "green"),
        opacity = 0.1,
        x0 = "2020-03-21",
        x1 = "2020-06-21",
        yref = "paper",
        y0 = 0,
        y1 = 1
      ),
      list(
        type = "area",
        fillcolor = "yellow",
        line = list(color = "yellow"),
        opacity = 0.15,
        x0 = "2020-06-21",
        x1 = "2020-09-23",
        yref = "paper",
        y0 = 0,
        y1 = 1
      ),
      list(
        type = "area",
        fillcolor = "chocolate",
        line = list(color = "chocolate"),
        opacity = 0.1,
        x0 = "2020-09-23",
        x1 = "2020-12-21",
        yref = "paper",
        y0 = 0,
        y1 = 1
      ),
      list(
        type = "area",
        fillcolor = "lightblue",
        line = list(color = "lightblue"),
        opacity = 0.2,
        x0 = "2020-12-21",
        x1 = "2020-12-31",
        yref = "paper",
        y0 = 0,
        y1 = 1
      )
    )
  ) %>%
  add_trace(x = ~time, y = ~mean_lufttemperatur, name = "Lufttemperatur °C", line = list(color = "black")) %>% 
  add_trace(x = ~time, y = ~windchill, name = "Gefühlte Temperatur (Windchill) °C", line = list(color = "red"), opacity = 0.2)

Dieser Plot wurde anhand von Hintergrundsfarben in Jahreszeiten unterteilt.

Farbe Jahreszeit
Blau Winter
Grün Frühling
Gelb Sommer
Braun Herbst

Aufgrund der visuellen Zeitreihenanalyse verwerfen wir die Hypothese, da in diesem Jahr die mittlere Tagestemperatur im Sommer regelmässig über 0°C steigt.

4.3 Auf dem Jungfraujoch ist es kurz vor Sonnenaufgang am kältesten.

plot <- data %>%
  group_by(time = format(time, "%H:%M")) %>%
  summarise(
    mean_lufttemperatur = mean(lufttemperatur, na.rm = T),
    mean_luftfeuchtigkeit = mean(luftfeuchtigkeit, na.rm = T),
    mean_windgeschwindigkeit = mean(windgeschwindigkeit, na.rm = T),
    mean_luftdruck = mean(luftdruck, na.rm = T),
    sonnenscheindauer_h = mean(sonnenscheindauer, na.rm = T)
  )

plot_ly(
  data = plot,
  type = "scatter",
  mode = "lines",
  width = 900,
  height = 700
) %>%
  add_trace(x = ~time, y = ~mean_lufttemperatur, name = "Lufttemperatur °C") %>%
  add_trace(x = ~time, y = ~mean_luftfeuchtigkeit, name = "Luftfeuchtigkeit in %", visible = "legendonly") %>%
  add_trace(x = ~time, y = ~sonnenscheindauer_h, name = "Sonnenscheindauer in h", visible = "legendonly") %>%
  add_trace(x = ~time, y = ~mean_windgeschwindigkeit, name = "Windgeschwindigkeit in m/s", visible = "legendonly") %>%
  add_trace(x = ~time, y = ~mean_luftdruck, name = "Luftdruck in hPa", visible = "legendonly") %>%
  layout(
    showlegend = TRUE,
    title = "Durchschnittliche Temperatur über den Tag auf dem Jungfraujoch im Jahr 2020",
    xaxis = list(
      title = "Uhrzeit",
      rangeslider = list(visible = T),
      rangeselector = list(
        buttons = list(
          list(count = 1, label = "1m", step = "month", stepmode = "backward"),
          list(step = "all")
        )
      ),
      zerolinecolor = "#C5C5C5",
      zerolinewidth = 2,
      gridcolor = "#C5C5C5"
    ),
    yaxis = list(
      title = "",
      zerolinecolor = "#C5C5C5",
      zerolinewidth = 2,
      gridcolor = "#C5C5C5"
    ),
    plot_bgcolor = "#ffffff",
    margin = 0.2,
    shapes = list(
      type = "rect",
      fillcolor = "yellow",
      line = list(color = "yellow"),
      opacity = 0.2,
      x0 = 33.4,
      x1 = 49.1,
      y0 = -6.1,
      y1 = -4.4
    )
  )

Markierung beim Plot:

Farbe Bedeutung
Gelb Zeitintervall zwischen frühesten und spätesten Sonnenaufgang 2020

Die mittlere Temperatur befindet sich tatsächlich zwischen vier und fünf Uhr am tiefsten Punkt. Da der berechnete früheste Sonnenenaufgang im Jahr 2020 kurz nach 05:30 (auf dem Berg oben vermutlich noch früher) war, bestätigen wir unsere Hypothese.

4.4 Die Sonne scheint auf dem Jungfraujoch das ganze Jahr etwa gleich lange.

Zur Beantwortung der Hypothese berechnen wir die die Anzahl Stunden, an welchen die Sonne gescheint hat. Dies machen wir mit der Granularität von einer Stunde.

4.4.1 Erstellung der Funktion für einfaches Plotten

visualize <- function(granularity) {
  plot <- data %>%
    group_by(time = floor_date(time, granularity)) %>%
    summarise(
      mean_lufttemperatur = mean(lufttemperatur, na.rm = T),
      mean_luftfeuchtigkeit = mean(luftfeuchtigkeit, na.rm = T),
      mean_windgeschwindigkeit = mean(windgeschwindigkeit, na.rm = T),
      mean_luftdruck = mean(luftdruck, na.rm = T),
      sonnenscheindauer_h = sum(sonnenscheindauer, na.rm = T) / 60
    )

  plot_ly(
    data = plot,
    type = "scatter",
    mode = "lines",
    width = 900,
    height = 700
  ) %>%
    add_trace(x = ~time, y = ~sonnenscheindauer_h, name = "Sonnenscheindauer in h") %>%
    layout(
      showlegend = FALSE,
      title = "Sonnenscheindauer auf dem Jungraujoch im 2020 in Stunden",
      xaxis = list(
        title = "Zeitachse",
        rangeslider = list(visible = T),
        rangeselector = list(
          buttons = list(
            list(count = 1, label = "1m", step = "month", stepmode = "backward"),
            list(step = "all")
          )
        ),
        zerolinecolor = "#ffff",
        zerolinewidth = 2,
        gridcolor = "ffff"
      ),
      yaxis = list(
        title = "",
        zerolinecolor = "#ffff",
        zerolinewidth = 2,
        gridcolor = "ffff"
      ),
      plot_bgcolor = "#e5ecf6",
      margin = 0.2
    )
}

4.4.2 Granularity Hour

visualize("hour")

Mit stündlichen Daten kann unsere Hypothese nicht beantwortet werden. Wir wechseln deshalb auf tägliche Werte.

4.4.3 Granularity Day

visualize("day")

Anhand täglicher Werte können wir unsere Hypothese immernoch nicht beantworten, die Grafik ist noch viel zu unübersichtlich. Wir schalten deshalb auf wöchentliche Werte.

4.4.4 Granularity Week

visualize("week")

Die Sonnenscheindauer variiert durch das ganze Jahr stark, deswegen verwerfen wir unsere Hypothese. Vermutlich waren das Schlechtwetterperioden mit viel Bewölkung über mehrere Tage oder Wochen. Für diese Hypothese würde sich ein Vergleich über mehrere Jahre gut anbieten.